/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = wtc_tcb_user.c                                     */
/*  NOTE      =                                                    */
/*  DATE      = 2015/08/25 by songbb                               */
/*******************************************************************/

#include "frreport_comm.h"

#include "../wtc_core.h"
#include "../wtc_comm.h"
#include "../wtc_mar.h"
#include "../typed/wtc_typedbuffer.h"
#include "wtc_tcb_user.h"

int wtc_tcb_user_tmpostrecv(Conntrack *p_st_conn
                            , Apm_packet *p_analyze_in
                            , L7session_wtc *p_st_sess
                            , L7_wtc_packet *p_st_wtc_packet
                            , int i_recv_size
                            , int i_hint_index
                            , Frreport_body_data **pp_st_body)
{
    char p_scratch[150] = {'\0'};
    char *p_type = NULL;
    unsigned int ui_type_len = 0;
    char *p_subtype = NULL;
    unsigned int ui_subtype_len = 0;
    typedbufferfunc f_typedbufferfunc = NULL;
    int i_pad_bytes = wtc_mar_roundup4(i_recv_size) - i_recv_size;
    int i_skip_size = i_pad_bytes;
    Frreport_body_data *p_st_body = NULL;

    WTC_PRINT_WARN("i_recv_size:[%d]\n", i_recv_size);
    WTC_PRINT_WARN("i_pad_bytes:[%d]\n", i_pad_bytes);

    if (wtc_mar_decode_string(p_st_sess, p_scratch, 150, p_st_wtc_packet, &p_type, &ui_type_len) != FR_SUCC)
        goto error;
    i_recv_size -= wtc_xdr_length_string(p_type, ui_type_len);
    WTC_PRINT_FATAL("p_type:[%s]\n", p_type);

//    if (p_analyze_in->st_timestamp.tv_usec == 166763)
//    {
//        printf("aa\n");
//    }

    if (wtc_mar_decode_string(p_st_sess, p_scratch, 150, p_st_wtc_packet, &p_subtype, &ui_subtype_len) != FR_SUCC)
        goto error;
    i_recv_size -= wtc_xdr_length_string(p_subtype, ui_subtype_len);
    if (p_subtype)
        WTC_PRINT_FATAL("p_subtype:[%s]\n", p_subtype);

    i_skip_size += i_recv_size;

    if ((f_typedbufferfunc = wtc_create_typedbuffer(i_hint_index, p_type, p_subtype)) == NULL)
    {
        if (strcmp(p_type, APM_WTC_CARRAY_STRING) == 0 && i_skip_size > 4)
        {
            unsigned int ui_lle_magic = 0;
            if (bytebuff_peek_int(p_st_wtc_packet->p_st_packet, 4, &ui_lle_magic, BYTE_BIG_ENDIAN) != FR_SUCC)
                goto error;
            if (ui_lle_magic == APM_WTC_LLE_MAGIC)
            {
                // TODO: unpack lle
                WTC_PRINT_CRIT("unpack lle\n");
                if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) i_skip_size) != FR_SUCC)
                    goto error;
                goto success;
            }
        }

        if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
            goto error;
        if (wtc_add_typedbuffer(p_st_conn, p_type, p_subtype, 0, p_st_wtc_packet, (unsigned int) i_skip_size, p_st_body) != FR_SUCC)
            goto error;
    }
    else
    {
        if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
            goto error;
        if (f_typedbufferfunc(p_st_conn, p_st_sess, p_st_wtc_packet, i_recv_size, p_st_body) != FR_SUCC)
            goto error;
    }

    *pp_st_body = p_st_body;

success:
    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    return FR_SUCC;
error:
    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}



//////////////////////// for analyze direction
int wtc_tcb_user_tmpostrecv_fad(int i_recv_size
                                , int i_hint_index
                                , char *p_payload
                                , unsigned int ui_payload_len
                                , unsigned int *p_ui_offset)
{
    WTC_PRINT_INFO("wtc_tcb_user_tmpostrecv_fad...\n");
    char p_scratch[150] = {'\0'};
    char *p_type = NULL;
    unsigned int ui_type_len = 0;
    char *p_subtype = NULL;
    unsigned int ui_subtype_len = 0;
    typedbufferfunc_fad f_typedbufferfunc_fad = NULL;
    int i_pad_bytes = wtc_mar_roundup4(i_recv_size) - i_recv_size;
    int i_skip_size = i_pad_bytes;

    if (wtc_mar_decode_string_fad(p_payload, ui_payload_len, p_ui_offset, p_scratch, 150, &p_type, &ui_type_len) != FR_SUCC)
        goto error;
    i_recv_size -= wtc_xdr_length_string(p_type, ui_type_len);
    WTC_PRINT_FATAL("p_type:[%s]\n", p_type);

    if (wtc_mar_decode_string_fad(p_payload, ui_payload_len, p_ui_offset, p_scratch, 150, &p_subtype, &ui_subtype_len) != FR_SUCC)
        goto error;
    i_recv_size -= wtc_xdr_length_string(p_subtype, ui_subtype_len);
    if (p_subtype)
        WTC_PRINT_FATAL("p_subtype:[%s]\n", p_subtype);

    i_skip_size += i_recv_size;

    if ((f_typedbufferfunc_fad = wtc_create_typedbuffer_fad(i_hint_index, p_type, p_subtype)) == NULL)
    {
        if (strcmp(p_type, APM_WTC_CARRAY_STRING) == 0 && i_skip_size > 4)
        {
            unsigned int ui_lle_magic = 0;
            if (wtc_peek_int(p_payload, ui_payload_len, p_ui_offset, &ui_lle_magic) != FR_SUCC)
                goto error;
            if (ui_lle_magic == APM_WTC_LLE_MAGIC)
            {
                WTC_PRINT_CRIT("unpack lle\n");
                if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_skip_size) != FR_SUCC)
                    goto error;
                goto success;
            }
        }

        if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_skip_size) != FR_SUCC)
            goto error;
    }
    else
    {
        if (f_typedbufferfunc_fad(i_recv_size, p_payload, ui_payload_len, p_ui_offset) != FR_SUCC)
            goto error;
    }

success:
    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    return FR_SUCC;
error:
    wtc_free((void **) &p_type);
    wtc_free((void **) &p_subtype);
    return FR_FAIL;
}
